home *** CD-ROM | disk | FTP | other *** search
- #include <io.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <windows.h>
- #include <winbase.h>
- #include <time.h>
- #include <direct.h>
- #include <sys/timeb.h>
-
- #define TEMP_PREFIX_LENGTH 8 // Length of temporary file prefix excluding null terminator
- #define DATA_BUFFER_LENGTH 1000 // Length of data buffer.
-
- #define MAX_FILE_ATTEMPTS 10 // Number of times to attempt creating temp file.
- #define ACK_RETRY_MILLISECONDS 250 // Number of milliseconds for each retry attempt to read ACK file.
- #define ACK_TIMEOUT_SECONDS 60 // Number of seconds until attempts to read ACK file time out.
-
- #define SERVER_INACCESSIBLE_TITLE_LOC "Server Inaccessible"
- #define SERVER_INACCESSIBLE_TEXT_LOC "Communication with the server is not possible at this time."
- #define SERVER_TIMEOUT_TITLE_LOC "Server Timeout"
- #define SERVER_TIMEOUT_TEXT_LOC "The server timed out. It is probably too busy to fulfill your request."
- #define SERVER_NODATA_TITLE_LOC "Server Error"
- #define SERVER_NODATA_TEXT_LOC "A server error occurred. No return data was sent."
-
- void errorform( char *errorstring, char *errortitle );
-
- void main( int argc, char *argv[] )
- {
-
- char tmpPrefix[TEMP_PREFIX_LENGTH+1];
- char tmpFolder[] = "\\temp";
- char tmpName[_MAX_PATH];
-
- char *t1 = NULL;
- char *tempbuffer = NULL;
-
- char datFileName[_MAX_PATH];
- char ackFileName[_MAX_PATH];
- char atnFileName[_MAX_PATH];
-
- FILE *datFile = NULL;
- FILE *atnFile = NULL;
- FILE *tempFile = NULL;
- struct _timeb timebuffer;
-
-
- char buffer[DATA_BUFFER_LENGTH];
- int cont_len, bytesread, fileattempts;
- time_t begintout, chktout;
- char **envptr;
- fpos_t pos;
-
- // Turn stdin buffering off
- setvbuf( stdin, NULL, _IONBF, 0 );
-
- // Create server.app compatible temporary folder.
- // Note: Server.app is looking for files in <current drive>:\temp,
- // not in the actual system temporary folder.
- _mkdir( tmpFolder );
-
- // Seed random number generator and zero fileattempts counter.
- _ftime( &timebuffer );
- srand( ((timebuffer.time & 0xFF)<<10) | timebuffer.millitm );
- fileattempts = 0;
-
- for (;;)
- {
-
- fileattempts++;
-
- // If we've tried MAX_FILE_ATTEMPTS times, give error message.
- if ( fileattempts > MAX_FILE_ATTEMPTS )
- {
- errorform( SERVER_INACCESSIBLE_TEXT_LOC, SERVER_INACCESSIBLE_TITLE_LOC );
- goto CleanupAndExit;
- }
-
- // Create random file name. Format is "VF" plus unique 4 digit hex number
- // representing the processid, plus 2 digit random number (in case multiple
- // machines are running the CGI scripts).
- sprintf( tmpPrefix, "VF%04X%02X", (DWORD) GetCurrentProcessId(), rand() & 0xFF);
-
- // Build temporary file name.
- sprintf( tmpName, "%s\\%s", tmpFolder, tmpPrefix );
-
- // Create the names for the three files.
- sprintf( datFileName, "%s.dat", tmpName );
- sprintf( ackFileName, "%s.ack", tmpName );
- sprintf( atnFileName, "%s.atn", tmpName );
-
- // Create data file.
- datFile = fopen( datFileName, "a" );
-
- // Make sure data file didn't already exist.
- if ( NULL != datFile )
- {
- // Seek to the end of the file.
- fseek( datFile, 0, SEEK_END );
- if( 0 == fgetpos( datFile, &pos ) )
- {
- // We know fgetpos was successful, now check position.
- // If pos is zero, we know we have a new file and can break out of loop.
- if ( 0 == pos ) break;
- }
- fclose( datFile );
- }
-
- }
-
- // We could check REQUEST_METHOD here, but what would be the point?
- // If CONTENT_LENGTH is NULL, we won't read the stdin, otherwise we will.
- // This is entirely for POST method requests.
- t1 = getenv( "CONTENT_LENGTH" );
- if ( NULL != t1 )
- {
- cont_len = atoi( t1 );
-
- tempbuffer = (char *) malloc( sizeof(char) * cont_len );
- if ( NULL == tempbuffer )
- {
- goto CleanupAndExit;
- }
-
- bytesread = fread( tempbuffer, sizeof(char), cont_len, stdin );
- if ( 0 != bytesread )
- fwrite( tempbuffer, sizeof(char), bytesread, datFile );
-
- free( tempbuffer );
- }
-
- // This part reads all of the environment variables and sends
- // them along in the DAT file as well. All ampersand delimited.
- envptr = environ;
- while ( NULL != *envptr )
- {
- fputs( "&", datFile );
- fputs( *envptr, datFile );
- envptr++;
- }
- fclose( datFile );
-
- // Create ATN File
- atnFile = fopen( atnFileName,"w" );
- if ( NULL == atnFile )
- {
- errorform( SERVER_INACCESSIBLE_TEXT_LOC , SERVER_INACCESSIBLE_TITLE_LOC );
- goto CleanupAndExit;
- }
-
- fclose( atnFile );
-
- _flushall();
-
- // Wait for Server to ACK
- time( &begintout );
- do
- {
- tempFile = fopen( ackFileName, "r" );
- if ( NULL != tempFile ) break; // Break before sleep if successful.
- time( &chktout );
- Sleep( ACK_RETRY_MILLISECONDS );
- //if _access() can't find the file, then the query is currently being processed.
- //Keep looping for another ACK_TIMEOUT_SECONDS.
- } while ( ( NULL == tempFile ) && (( difftime( chktout, begintout ) < ACK_TIMEOUT_SECONDS )
- || ((_access(atnFileName,0) == -1) && ( difftime( chktout, begintout ) < (2*ACK_TIMEOUT_SECONDS) ))));
-
- if ( NULL != tempFile )
- {
- fclose( tempFile );
- }
- else
- {
- errorform( SERVER_TIMEOUT_TEXT_LOC , SERVER_TIMEOUT_TITLE_LOC);
- goto CleanupAndExit;
- }
-
- // Send the Data file to stdout.
- datFile = fopen( datFileName, "r" );
- if ( NULL == datFile )
- {
- errorform( SERVER_NODATA_TEXT_LOC , SERVER_NODATA_TITLE_LOC);
- goto CleanupAndExit;
- }
- else
- {
- // Return results to web server.
- while ( !feof( datFile ) )
- {
- if ( NULL != fgets( buffer, DATA_BUFFER_LENGTH, datFile ) )
- printf( "%s", buffer );
- }
- fclose( datFile );
- }
-
- CleanupAndExit:
-
- // Close all file handles.
- _fcloseall();
-
- // Remove temporary files.
- remove( ackFileName );
- remove( datFileName );
- remove( atnFileName );
-
- return;
-
- }
-
- void errorform( char *errorstring, char *errortitle )
- {
- printf( "Content-Type: text/html\n\n" );
- printf( "<head><title>%s</title></head>\n", errortitle );
- printf( "<body>\n<h1>%s</h1>\n", errortitle );
- printf( "%s<hr>\n</body>", errorstring );
- }
-